package main

import (
	"fmt"
	"reflect"
)

// method 获取有点问题，  其余没问题， 需要后续查找一下1.21的更新变化
type Student struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Score int    `json:"score"`
}

func (s *Student) GetInfo() string {
	var str = fmt.Sprintf("姓名:%v , 年龄:%v, 成绩:%v\n", s.Name, s.Age, s.Score)
	return str
}

func (s *Student) SetInfo(name string, age int, score int) {
	s.Name = name
	s.Age = age
	s.Score = score
}

func (s *Student) Print() {
	fmt.Println("打印。。。。。。")
}

func PrintStructField(s interface{}) {
	// 判断参数是不是结构体
	t := reflect.TypeOf(s)
	v := reflect.ValueOf(s)
	if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {
		fmt.Println("参数不是结构体")
		return
	}
	// 获取结构体字段 1
	filed0 := t.Field(0)
	fmt.Println(filed0.Name, filed0.Type, filed0.Tag, filed0.Tag.Get("json")) // Name   string   json:"name"  name
	// 获取结构体字段 2
	filed1, ok := t.FieldByName("Name")
	if ok {
		fmt.Println(filed1.Name, filed1.Type, filed1.Tag, filed1.Tag.Get("json")) // Name   string   json:"name"  name
	}

	// 获取结构体字段数量
	filedLen := t.NumField()
	fmt.Println(filedLen) // 3

	// 获取值
	value0 := v.Field(0)
	fmt.Println(value0)               // 张三
	fmt.Println(v.FieldByName("Age")) // 18
	fmt.Println("================================")
	// 获取结构体方法

	method0, ok := t.MethodByName("GetInfo")
	if ok {
		fmt.Println(method0.Name)
		fmt.Println(method0.Type)
	}

	// 通过值变量执行方法
	// v.MethodByName("Print").Call(nil) // go 1.21好像出现了变化，回头在查吧

}
func main() {

	stu1 := Student{
		Name:  "张三",
		Age:   18,
		Score: 110,
	}

	PrintStructField(stu1)
}
